package com.smile.cloud.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.smile.cloud.admin.bo.UserDetail;
import com.smile.cloud.admin.dto.UserRegisterForm;
import com.smile.cloud.admin.service.AuthService;


import com.smile.cloud.admin.vo.UserDetailVo;
import com.smile.cloud.common.base.result.BaseResultEnum;
import com.smile.cloud.redisConfig.service.RedisService;
import com.smile.cloud.common.base.service.ConvertService;
import com.smile.cloud.common.base.exception.BizException;
import com.smile.cloud.mbg.base.model.*;
import com.smile.cloud.mbg.base.service.*;
import com.smile.cloud.security.util.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @ClassName UmsAdminServiceImpl
 * @Description TODO
 * @author smile
 * @Date 2020/4/11
 * @Version V1.0
 **/
@Service
@Slf4j
public class AuthServiceImpl implements AuthService {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private RedisService redisService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private ConvertService convertService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysRoleResourceService sysRoleResourceService;
    @Autowired
    private SysResourceService sysResourceService;
    @Value("${jwt.expiration}")
    private Long expiration;

    @Override
    public SysUser register(UserRegisterForm userRegisterForm) throws Exception {
        SysUser sysUser = convertService.convert(userRegisterForm, SysUser.class);
        sysUser.setCreateTime(new Date());
        sysUser.setCreateBy(0);
        sysUser.setUpdateTime(new Date());
        sysUser.setUpdateBy(0);
        //查询是否有相同uuid的用户
        String uuidAccount = userRegisterForm.getSaasCode() + "_" + userRegisterForm.getPhone();
        sysUser.setUuidAccount(uuidAccount);
        QueryWrapper<SysUser> query = new QueryWrapper<>();
        query.lambda()
                .eq(SysUser::getUuidAccount, uuidAccount)
                .eq(SysUser::getSaasCode, userRegisterForm.getSaasCode());
        List<SysUser> umsAdminList = sysUserService.list(query);
        if (umsAdminList.size() > 0) {
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(sysUser.getPassword());
        sysUser.setPassword(encodePassword);
        sysUserService.save(sysUser);
        return sysUser;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        //密码需要客户端加密后传递
        try {
            if (redisService.hasKey(username) && redisService.get(username) != null) {
                redisService.set(username, token, expiration);
                return token = (String) redisService.get(username);
            }
            UserDetails userDetails = loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
            //缓存token
            redisService.set(username, token, expiration);

//            updateLoginTimeByUsername(username);
//            insertLoginLog(username);
        } catch (AuthenticationException e) {
            log.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    @Override
    public UserDetailVo getUserDetailByToken(String token) throws Exception {
        UserDetailVo userDetailVo = new UserDetailVo();
        String userName = jwtTokenUtil.getUserNameFromToken(token);
        if (userName == null) {
            throw new BizException(BaseResultEnum.UNAUTHORIZED);
        }
        QueryWrapper<SysUser> query = new QueryWrapper<>();
        query.lambda()
                .eq(SysUser::getUuidAccount, userName)
                .eq(SysUser::getEnableState, 1)
                .eq(SysUser::getIsDelete, 0);
        SysUser user = sysUserService.getOne(query);
        if (user == null) {
            return userDetailVo;
        }
        userDetailVo.setUser(user);
        QueryWrapper<SysUserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, user.getUserId());
        List<SysUserRole> userRoleList = sysUserRoleService.list(userRoleQueryWrapper);
        //从角色表获取角色
        if (CollectionUtils.isNotEmpty(userRoleList)) {
            Set<Integer> roleIdSet = userRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
            List<SysRole> roleList = sysRoleService.listByIds(roleIdSet);
            if (CollectionUtils.isNotEmpty(roleList)) {
                userDetailVo.setRoleList(roleList);
                //获取资源
                Set<Integer> realRoleIdSet = roleList.stream().map(SysRole::getRoleId).collect(Collectors.toSet());
                QueryWrapper<SysRoleResource> roleResourceQueryWrapper = new QueryWrapper<>();
                roleResourceQueryWrapper.lambda().in(SysRoleResource::getRoleId, realRoleIdSet);
                List<SysRoleResource> roleResourceList = sysRoleResourceService.list(roleResourceQueryWrapper);
                if (CollectionUtils.isNotEmpty(roleResourceList)) {
                    Set<Integer> resourceIdSet = roleResourceList.stream().map(SysRoleResource::getResourceId).collect(Collectors.toSet());
                    List<SysResource> sysResourceList = sysResourceService.listByIds(resourceIdSet);
                    userDetailVo.setResourceList(sysResourceList);
                }
            }
        }
        return userDetailVo;
    }
//
//    /**
//     * 添加登录记录
//     * @param username 用户名
//     */
//    private void insertLoginLog(String username) {
//        UmsAdmin admin = getAdminByUsername(username);
//        UmsAdminLoginLog loginLog = new UmsAdminLoginLog();
//        loginLog.setAdminId(admin.getId());
//        loginLog.setCreateTime(new Date());
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//        loginLog.setIp(request.getRemoteAddr());
//        loginLogMapper.insert(loginLog);
//    }
//
//    /**
//     * 根据用户名修改登录时间
//     */
//    private void updateLoginTimeByUsername(String username) {
//        UmsAdmin record = new UmsAdmin();
//        record.setLoginTime(new Date());
//        UmsAdminExample example = new UmsAdminExample();
//        example.createCriteria().andUsernameEqualTo(username);
//        adminMapper.updateByExampleSelective(record, example);
//    }

    @Override
    public String refreshToken(String oldToken) {
        return jwtTokenUtil.refreshHeadToken(oldToken);
    }


    @Override
    public UserDetails loadUserByUsername(String username) {
        SysUser sysUser = null;
        List<SysRole> roleList = new ArrayList<>();
        QueryWrapper<SysUser> query = new QueryWrapper<>();
        query.lambda()
                .eq(SysUser::getUuidAccount, username)
                .eq(SysUser::getEnableState, 1)
                .eq(SysUser::getIsDelete, 0);
        List<SysUser> sysUserList = sysUserService.list(query);
        if (CollectionUtils.isNotEmpty(sysUserList)) {
            sysUser = sysUserList.get(0);
        } else {
            throw new UsernameNotFoundException(String.format("用户'%s'不存在", username));
        }
        //从中间表查询用户角色
        QueryWrapper<SysUserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getUserId());
        List<SysUserRole> userRoleList = sysUserRoleService.list(userRoleQueryWrapper);
        //从角色表获取角色
        if (CollectionUtils.isNotEmpty(userRoleList)) {
            Set<Integer> roleIdSet = userRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
            List<SysRole> sysRoleList = sysRoleService.listByIds(roleIdSet);
            if (CollectionUtils.isNotEmpty(sysRoleList)) {
                for (SysRole xfpRole : sysRoleList) {
                    SysRole role = SysRole.builder()
                            .roleId(xfpRole.getRoleId())
                            .roleName(xfpRole.getRoleName())
                            .roleNo("role_" + xfpRole.getSaasCode() + "_" + xfpRole.getRoleNo())
                            .build();
                    roleList.add(role);
                }
            }
        }
        return new UserDetail(sysUser, roleList);

    }
}
